package com.mttang.util;

import java.io.File;
import java.io.IOException;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

@SuppressWarnings("unchecked")
public class FileUploadUtil {

    /**
     * 上传文件的内存缓冲大小，默认为100K
     */
    private static final int   sizeThreshold             = 1024 * 100;

    /**
     * 响应的字符编码，默认为“UTF-8”
     */
    public static final String responseCharacterEncoding = "UTF-8";

    /**
     * 上传文件的最大尺寸,默认值为10M
     */
    public static final long   sizeMax                   = 1024 * 1024 * 10;
    /**
     * 上传文件的缓冲目录
     */
    public static final String filePathRepository        = "Repository";
    // /**
    // * 上传文件的当前路径
    // */
    // public static final String filePathCurrent = "current";

    private static Log         logger                    = LogFactory.getLog(FileUploadUtil.class);

    public static void doFileUpload(HttpServletRequest request, HttpServletResponse response, String currentFolder,
                                    Map condition) {
        if (logger.isInfoEnabled()) {
            logger.info("---doFileUpload.Begin()---");
        }
        String fileName = null;
        try {

            if (ServletFileUpload.isMultipartContent(request)) {
                DiskFileItemFactory factory = new DiskFileItemFactory();

                File repositoryFile = new File(currentFolder + "/" + filePathRepository);// 设置大文件的缓冲目录
                if (!repositoryFile.exists()) {
                    boolean success = repositoryFile.mkdirs();
                    if (logger.isInfoEnabled()) {
                        logger.info("make file: '" + repositoryFile + "' " + success);
                    }
                }
                factory.setRepository(repositoryFile);// 指定上传文件的临时目录

                factory.setSizeThreshold(sizeThreshold);// 设置内存缓冲大小

                ServletFileUpload upload = new ServletFileUpload(factory);

                upload.setSizeMax(sizeMax);// 指定上传单个文件的最大字节数
                upload.setSizeMax(sizeMax * 5);// 指定一次上传文件的总字节数
                response.setCharacterEncoding(responseCharacterEncoding); // 设置响应的字符编码

                List<FileItem> items = null;
                try {
                    items = upload.parseRequest(request);
                    if (logger.isInfoEnabled()) {
                        logger.info("解析文件成功");
                    }
                } catch (FileUploadException e) {
                    logger.warn("解析文件失败", e);
                    throw new ParamException(MessageInfo.INFO_PARSE_FILE_ERROR);
                }
                if (items != null && items.size() > 0) {
                    // 数据处理
                    for (FileItem item : items) {
                        if (item.isFormField()) {
                            condition.put(item.getFieldName(), item.getString("UTF-8"));
                        } else {
                            fileName = item.getName().substring(item.getName().lastIndexOf("."));// 获取上传文件的文件名
                            fileName = renameFileToRandom(fileName);
                            //
                            // BufferedInputStream in = new BufferedInputStream(item.getInputStream());// 获取文件输入流
                            // BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(new
                            // File(currentFolder+ fileName)));// 获取文件输出流
                            // Streams.copy(in, out, true);// 开始把文件写到指定的上传目录
                            //
                            item.write(new File(currentFolder + fileName));
                        }
                    }
                }

                // FileItemIterator fileItem = upload.getItemIterator(request);//解析request请求，返回FileItemIterator集合
                // while (fileItem.hasNext()) {
                // FileItemStream fis = fileItem.next();
                // if (!fis.isFormField() && fis.getName().length() > 0) {//文件域
                // fileName = fis.getName().substring(fis.getName().lastIndexOf("."));// 获取上传文件的文件名
                // fileName = renameFileToRandom(fileName);
                // BufferedInputStream in = new BufferedInputStream(fis.openStream());// 获取文件输入流
                // BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(new File(currentFolder
                // + fileName)));// 获取文件输出流
                // Streams.copy(in, out, true);// 开始把文件写到指定的上传目录
                // }
                // }
            }

            condition.put("attachment1", fileName);
        } catch (Exception ex) {
            ex.printStackTrace();
            logger.error(ex);
        } finally {

        }
    }
    
    /**
     * 上传文件并返回表单数据及保存的文件名
     * @param request
     * @param targetFolder
     * @return
     * @throws Exception
     */
    public static Map<String, Object> doFileUpload(HttpServletRequest request, String baseDir, String fileFolder) throws Exception{
    	Map<String, Object> condition = new HashMap<String, Object>();
    	if(ServletFileUpload.isMultipartContent(request)){
            File repositoryFile = new File(baseDir + File.separator + filePathRepository);// 设置大文件的缓冲目录
            if (!repositoryFile.exists()) {
                repositoryFile.mkdirs();
            }

            DiskFileItemFactory factory = new DiskFileItemFactory();
            factory.setRepository(repositoryFile);//指定上传文件的临时目录
            factory.setSizeThreshold(sizeThreshold);// 设置内存缓冲大小
            ServletFileUpload upload = new ServletFileUpload(factory);
            
            upload.setSizeMax(sizeMax);// 指定上传单个文件的最大字节数
            upload.setSizeMax(sizeMax*5);//指定一次上传文件的总字节数
    	
    		List<FileItem> items = upload.parseRequest(request);
    		if(null != items && !items.isEmpty()){
    			for (FileItem item : items){
					if(item.isFormField()){
						condition.put(item.getFieldName(), item.getString("UTF-8"));
					}else{
						if(!org.apache.commons.lang.StringUtils.isBlank(item.getName())){
							String fileName = item.getName().substring(item.getName().lastIndexOf("."));// 获取上传文件的文件名
							String fullFileName = getFilePathTempCurrent(fileFolder) + "/" + renameFileToRandom(fileName);
							File file = new File(baseDir + fullFileName); 
							if(!file.getParentFile().exists()){
								file.getParentFile().mkdirs();
							}
							item.write(file);	//文件上传
							condition.put(item.getFieldName(), fullFileName);
						}
    				}
    			}
    		}
    	}
    	 
    	return condition;
	}

    private static String getFilePathRepository(String tempUploadWindow, String tempUploadLinux) {

        String separator = System.getProperties().getProperty("file.separator");
        boolean isLinux = separator.equals("/");
        String filePathPrefix = isLinux ? tempUploadLinux : tempUploadWindow;
        return filePathPrefix + "/" + filePathRepository;
    }

    private static String getFilePathTempCurrent(String currentFolder) {

        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
        String dateStr = dateFormat.format(new Date());
        return "/" + currentFolder + "/" + dateStr;
    }

    private static String getFilePathCurrent(String tempUploadWindow, String tempUploadLinux, String currentFolder) {
        String separator = System.getProperties().getProperty("file.separator");
        String filePathPrefix = separator.equals("/") ? tempUploadLinux : tempUploadWindow;
        // SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
        // String dateStr = dateFormat.format(new Date());
        return filePathPrefix + getFilePathTempCurrent(currentFolder);
    }

    private static String getDestinationFilePath(String destpath, String currentFolder) {
        return destpath + getFilePathTempCurrent(currentFolder);
    }

    /**
     * 重新设置文件名UUID
     */
    protected static String renameFileToRandom(String fileName) {
        // String oldName = paramMap.get(key);
        if (fileName != null && fileName.trim().length() > 0) {
            String newName = getRandomUUID() + fileName;
            // Object typePath = this.getInfoFileConfigure().getFileTypePath(ext);
            // if (typePath != null && typePath.toString().length() > 0) {
            // newName = typePath + "/" + newName;
            // }

            // newFileMap.put(key, newName);
            return newName;
        }

        return "";
    }

    /**
     * 获取文件扩展名 没有返回""
     * 
     * @param name 文件名
     * @return
     */
    public static String getExtension(String name) {
        if (name == null) {
            return "";
        }

        int index = name.lastIndexOf('.');
        if (index > 0) {
            return name.substring(index + 1);
        }
        return "";
    }

    /**
     * 生成uuid文件名
     * 
     * @return
     */
    public static String getRandomUUID() {
        return UUID.randomUUID().toString();
    }

    public static String generateFormNo() {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
        String dateStr = dateFormat.format(new Date());

        Random random = new Random();
        int randomInt = random.nextInt(9999);

        NumberFormat numberFormat = new DecimalFormat("0000");
        String randomStr = numberFormat.format(randomInt);

        return dateStr + randomStr;

    }

    private static void scpWrite(String hostName, String user, String localFile, String remoteFile) {
        // 先创建文件夹
        scpMkdir(remoteFile, hostName, user);

        // 再传递文件
        String command = "scp -r " + localFile + " " + user + "@" + hostName + ":" + remoteFile;
        if (logger.isInfoEnabled()) {
            logger.info("mkfile1=======" + command); // 整个命令日志
            // logger.debug("scp [" + localFile + "] to " + info.getRemoteHost() + info.getRemotePath());
        }
        Process p = null;
        try {
            Runtime rt = Runtime.getRuntime();
            p = rt.exec(command);
            if (logger.isInfoEnabled()) {
                logger.info("exec scp return " + p);
            }
            if (p.waitFor() != 0) {
                if (logger.isInfoEnabled()) {
                    logger.info("java call scp command is error");
                }
            }
        } catch (IOException e) {
            if (logger.isErrorEnabled()) {
                logger.error(e);
            }
        } catch (InterruptedException e) {
            if (logger.isErrorEnabled()) {
                logger.error(e);
            }
        }
    }

    public static void scpMkdir(String filePath, String hostName, String userName) {
        // String remote = html ? info.getRemoteHtmlPath() : info.getRemoteFilePath();
        // String[] hostArr = html ? info.getRemoteHtmlHosts() : info.getRemoteFileHosts();
        // String user = html ? info.getRemoteHtmlUser() : info.getRemoteFileUser();
        // if (remote.length() > 0) {
        // dir = remote + "/" + dir;
        // for (String host : hostArr) {
        String command = "ssh " + userName + "@" + hostName + " mkdir -p " + filePath;
        if (logger.isInfoEnabled()) {
            logger.info("mkdir2=======" + command); // 整个命令日志
        }
        Process p = null;
        try {
            Runtime rt = Runtime.getRuntime();
            p = rt.exec(command);
            if (logger.isDebugEnabled()) {
                logger.debug("exec ssh return " + p);
            }
            if (p.waitFor() != 0) {
                if (logger.isInfoEnabled()) {
                    logger.info("java call ssh command is error");
                }
            }
        } catch (IOException e) {
            if (logger.isErrorEnabled()) {
                logger.error(e);
            }
        } catch (InterruptedException e) {
            if (logger.isErrorEnabled()) {
                logger.error(e);
            }
        }
        // }
        // }
    }

}
